<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Reset_Synchronizer.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Filters an asynchronous reset signal so it can assert immediately and asynchronously, but can only release synchronously with a receiving clock (after 2 or 3 (plus `EXTRA_DEPTH`) cycles of latency), which avoids metastability issues should the reset release too close to the receiving clock edge.">
<title>Reset Synchronizer</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Reset_Synchronizer.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>Reset Synchronizer</h1>
<p>Filters an asynchronous reset signal so it can assert immediately and
 asynchronously, but can only release synchronously with a receiving clock
 (after 2 or 3 (plus <code>EXTRA_DEPTH</code>) cycles of latency), which avoids
 metastability issues should the reset release too close to the receiving
 clock edge.</p>
<p>Set the <code>RESET_ACTIVE_STATE</code> parameter to the value of your reset when
 active (e.g.: 0 for active-low reset).</p>
<p>If you are running near the speed or temperature limits of your silicon,
 you may have to add some extra synchronizer stages with the <code>EXTRA_DEPTH</code>
 parameter. Consult your datasheets.</p>
<h2>Implementation</h2>
<p>This design combines the internals of a <a href="./CDC_Bit_Synchronizer.html">CDC Bit
 Synchronizer</a> and of a <a href="./Register_areset.html">Register with
 Asynchronous Reset</a> (please see those modules for
 more background).  We cannot instantiate those modules here since we have
 to apply some attributes directly to <code>reg</code> values to make a good
 synchronizer, and the CDC Synchronizer module does not have a reset.</p>
<h2>Usage Notes and Limitations</h2>
<p>Much like a CDC Synchronizer, you can only synchronize a given reset bit in
 one place, as two synchronizers fed by the same input may have different
 output latencies due to metastability. Also, feed the <code>reset_in</code> input
 directly from a register, as combinational logic glitches could trigger
 spurious resets. Finally, you cannot place any of the registers into I/O
 registers: they are too far away from the main logic fabric to make a good
 synchronizer.</p>
<p><em>Make sure no logic under asynchronous reset feeds logic which is not also
 under reset, else metastability may happen in the latter logic since the
 reset assertion is not synchronous to the clock.</em> If you need reset
 assertion to be synchronous, use a <a href="./CDC_Bit_Synchronizer.html">CDC
 Synchronizer</a> instead.</p>
<p><strong>Also, note that introducing an asynchronous reset, even with synchronized
 release, may prevent any register retiming from ocurring in connected
 logic.</strong> Check your CAD tool results, and favour the plain <a href="./CDC_Bit_Synchronizer.html">CDC
 Synchronizer</a> instead.</p>
<h2>Use Cases</h2>
<ul>
<li>If your reset comes from an external pin, synchronize it to your system
 clock before using it. <em>You must make sure the external reset is not
 glitchy.</em></li>
<li>If you have logic which spans two clock domains, synchronize the reset
 from the first clock domain, considered the primary reset, into the second
 clock domain. This will reset both domains together and release the reset
 synchronously in the second clock domain, avoiding metastability. <em>This
 assumes a ready/valid handshake when exchanging data across the clock
 domains.</em></li>
<li>If you have I/O logic that is driven by an external data clock which may
 or may not be active, reset the I/O logic by synchronizing the system reset
 to the data clock: the I/O logic will stay in reset until the data clock
 becomes active. <em>This means the data clock must run for at least
 <code>3 + EXTRA_DEPTH</code> cycles before I/O transactions can begin.</em></li>
</ul>

<pre>
`default_nettype none

module <a href="./Reset_Synchronizer.html">Reset_Synchronizer</a>
#(
    parameter EXTRA_DEPTH           = 0,
    parameter RESET_ACTIVE_STATE    = 2   // Must be 0 (active-low) or 1 (active-high)
)
(
    input   wire    receiving_clock,
    // Necessary since the reset may be also used synchronously in the originating clock domain.
    // verilator lint_off SYNCASYNCNET
    input   wire    reset_in,
    // verilator lint_on  SYNCASYNCNET
    output  reg     reset_out
);

    initial begin
        reset_out = ~RESET_ACTIVE_STATE [0];
    end
</pre>

<h2>Synchronizer Registers</h2>
<p>The minimum valid synchronizer depth is 2. Add more stages if the design
 requires it. This usually happens near the highest operating frequencies.
 Consult your device datasheets.</p>

<pre>
    localparam DEPTH = 2 + EXTRA_DEPTH;
</pre>

<p>For Vivado, we must specify that the synchronizer registers should be
 placed close together (see: UG912), and to show up as part of MTBF reports.</p>
<p>For Quartus, specify that these register must not be optimized (e.g. moved
 into the input register of a DSP or BRAM) and to mark them as composing
 a synchronizer (and so be placed close together).</p>
<p>In both cases, we also specify that the registers must not be placed in I/O
 register locations.</p>

<pre>
    // Vivado
    (* IOB = "false" *)
    (* ASYNC_REG = "TRUE" *)

    // Quartus
    (* useioff = 0 *)
    (* PRESERVE *)
    (* altera_attribute = "-name SYNCHRONIZER_IDENTIFICATION \"FORCED IF ASYNCHRONOUS\"" *)

    reg sync_reg [DEPTH-1:0];

    integer i;

    initial begin
        for(i=0; i < DEPTH; i=i+1) begin
            sync_reg [i] = ~RESET_ACTIVE_STATE [0];
        end
    end
</pre>

<h2>Reset Logic</h2>
<p>Now, depending on the reset active state, we instantiate one of two cases,
 distinguished only by the active edge of the reset signal. (It's grotesque
 to have such code duplication, but it's the only way.)</p>
<p>When <code>reset_in</code> is asserted (as specified in <code>RESET_ACTIVE_STATE</code>),
 asynchronously place all synchronizer registers in reset, which immediately
 asserts <code>reset_out</code>. Then, when <code>reset_in</code> is released, the synchronizer
 will synchronously release <code>reset_out</code> after <code>DEPTH</code> or <code>DEPTH + 1</code> cycles,
 depending on the metastability of the first <code>sync_reg</code> register.</p>
<p>Finally, if <code>RESET_ACTIVE_STATE</code> is given a value other than 0 or 1, try to
 instantiate a non-existent module to force synthesis or simulation to fail
 immediately, with the instance name as the error message. It's ugly, but
 CAD tools usually ignore <code>$display()</code> and <code>$finish()</code> system functions
 during synthesis. </p>
<p><em>We must have this failsafe, else an invalid <code>RESET_ACTIVE_STATE</code> parameter
 could leave <code>reset_out</code> always inactive, causing hard-to-find, intermittent
 bugs in the logic dependent on <code>reset_out</code>.</em> Note the use of the identity
 operator (<code>===</code>) instead of the equality operator (<code>==</code>), so a parameter
 containing an <code>X</code> value does not implicitly match zero/false.</p>

<pre>
    generate
        if (RESET_ACTIVE_STATE === 0) begin

            always @(posedge receiving_clock, negedge reset_in) begin
                if (reset_in == RESET_ACTIVE_STATE [0]) begin
                    for(i = 0; i < DEPTH; i = i+1) begin
                        sync_reg [i] <= RESET_ACTIVE_STATE [0];
                    end
                end
                else begin
                    sync_reg [0] <= ~RESET_ACTIVE_STATE [0];
                    for(i = 1; i < DEPTH; i = i+1) begin
                        sync_reg [i] <= sync_reg [i-1]; 
                    end
                end
            end

        end
        else if (RESET_ACTIVE_STATE === 1) begin

            always @(posedge receiving_clock, posedge reset_in) begin
                if (reset_in == RESET_ACTIVE_STATE [0]) begin
                    for(i = 0; i < DEPTH; i = i+1) begin
                        sync_reg [i] <= RESET_ACTIVE_STATE [0];
                    end
                end
                else begin
                    sync_reg [0] <= ~RESET_ACTIVE_STATE [0];
                    for(i = 1; i < DEPTH; i = i+1) begin
                        sync_reg [i] <= sync_reg [i-1]; 
                    end
                end
            end

        end
        else begin

            // verilator lint_off DECLFILENAME
            NonExistentModuleForErrorChecking ERROR_RESET_ACTIVE_STATE_MUST_BE_0_OR_1 ();
            // verilator lint_on  DECLFILENAME

        end
    endgenerate

    always @(*) begin
        reset_out = sync_reg [DEPTH-1];
    end

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

